﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using thailandProject.Models;
using MvcFilters.Infrastructure.Filters;

namespace thailandProject.Controllers
{
    [ThailandAuthorize(3)]
    public class HomeController : Controller
    {
        [HttpGet]
        public ActionResult Index(string sortType)
        {
            int taskDays = -1;
            bool hideComplete = true;
            try
            {
                ViewBag.Header = "Dashboard";

                if (Session["taskSortType"] == null)
                    Session.Add("taskSortType", ""); //sortType will be empty on first load
                else
                {
                    Session["taskSortType"] = sortType ?? "";
                }

                if (Session["taskDays"] == null)
                    Session.Add("taskDays", 7);

                if (Session["hideComplete"] == null)
                    Session.Add("hideComplete", true);
                taskDays = (int)Session["taskDays"];
                hideComplete = (bool)Session["hideComplete"];
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return Index(taskDays, hideComplete.ToString().ToLowerInvariant());
        }

        [HttpPost]
        public ActionResult Index(int days, string hideCompleted)
        {
            Pair<List<TASK>, List<TASKTYPE>> result = new Pair<List<TASK>, List<TASKTYPE>>(new List<TASK>(), new List<TASKTYPE>());
            try
            {
                ViewBag.Header = "Dashboard";

                bool hideComplete = hideCompleted == "true" ? true : false;
                Session["taskDays"] = days;
                Session["hideComplete"] = hideComplete;
                string sortType = (string)Session["taskSortType"];

                List<TASK> taskList;
                DateTime dueDate = DateTime.Now.Date.AddDays(days);
                DateTime now = DateTime.Now.Date;
                ThailandEntities a = new ThailandEntities();

                if (!String.IsNullOrEmpty(sortType))
                {
                    int clientId;
                    if (Int32.TryParse(sortType, out clientId)) //See if the sorting is by a client's name.
                    {
                        var tasks = from task in a.TASKs
                                    from res in a.RESERVATIONs
                                    where task.resID == res.resID &&
                                    res.clientID == clientId &&
                                    (task.taskDueDate <= dueDate &&
                                    task.taskDueDate >= now) &&
                                    (!hideComplete || !task.taskComplete) //Always true if hideComplete is false. If it's true, then only return tasks that haven't been completed
                                    orderby task.taskDueDate
                                    select task;

                        taskList = tasks.ToList();
                    }
                    else
                    {
                        var tasks = from task in a.TASKs
                                    from taskType in a.TASKTYPEs
                                    where task.taskTypeID == taskType.taskTypeID &&
                                    (taskType.taskTypeName == sortType ||
                                    (task.taskTypeID == 0 && ((sortType == "Pickup" && task.taskName.Contains("Pickup")) ||
                                                              (sortType == "Dropoff" && task.taskName.Contains("Dropoff"))))) &&
                                    (task.taskDueDate <= dueDate &&
                                    task.taskDueDate >= now) &&
                                    (!hideComplete || !task.taskComplete) //Always true if hideComplete is false. If it's true, then only return tasks that haven't been completed
                                    orderby task.taskDueDate
                                    select task;

                        taskList = tasks.ToList();
                    }
                }//End to if sortType is not null or empty
                else
                {
                    var tasks = from task in a.TASKs
                                where task.taskDueDate <= dueDate &&
                                task.taskDueDate >= now &&
                                (!hideComplete || !task.taskComplete)
                                orderby task.taskDueDate
                                select task;

                    taskList = tasks.ToList();
                }

                //Sort through the task list. Remove any where the client is deactivated
                //I'm putting this here instead of in the query as not to break anything
                List<TASK> finalList = new List<TASK>();
                foreach(TASK t in taskList)
                {
                    if (t.RESERVATION.CLIENT.clientIsActive)
                        finalList.Add(t);
               }


                var taskTypes = from taskType in a.TASKTYPEs
                                where taskType.taskTypeID > 0 &&
                                taskType.isActive == true
                                select taskType;

                result = new Pair<List<TASK>, List<TASKTYPE>>(finalList, taskTypes.ToList());
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View(result);
        }

        [HttpGet]
        [ThailandAuthorize]
        public ActionResult EditTask(int taskId, string redirectURL)
        {
            Pair<string, Pair<TASK, List<TASKTYPE>>> result = new Pair<string, Pair<TASK, List<TASKTYPE>>>("-1", new Pair<TASK, List<TASKTYPE>>(new TASK(), new List<TASKTYPE>()));
            try
            {
                ViewBag.Header = "Edit Task";

                //Get the corresponding taskDetail and pass it to the view, along with the TaskTypes
                ThailandEntities e = new ThailandEntities();

                var taskDetails = from task in e.TASKs
                                  where task.taskID == taskId
                                  select task;

                var taskTypes = from taskType in e.TASKTYPEs
                                where taskType.isActive == true ||
                                taskType.taskTypeID == 0
                                select taskType;
                result = new Pair<string, Pair<TASK, List<TASKTYPE>>>(redirectURL, new Pair<TASK, List<TASKTYPE>>(taskDetails.ToList()[0], taskTypes.ToList()));
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View(result);
        }

        [HttpPost]
        [ThailandAuthorize]
        public ActionResult EditTask(string btnSubmit, FormCollection data)
        {
            string redirectURL = "";
            try
            {
                //Due to the unique way this form works, an automatic model binding won't work.
                //As such, the old object can't be returned. First, fetch it from the database
                ThailandEntities e = new ThailandEntities();
                int taskId = Convert.ToInt32(data["taskId"]);

                var taskDetails = from task in e.TASKs
                                  where task.taskID == taskId
                                  select task;

                TASK td = taskDetails.ToList()[0]; //Get the only entry in this list

                //If the "Save" button was pressed
                if (btnSubmit == "Save")
                {
                    //Create the new time
                    DateTime time = Convert.ToDateTime(data["taskDueDate"].ToString()); //By default, the time will be 12:00 AM
                    time = time.AddHours(Convert.ToInt32(data["taskTypeHour"].ToString()) + (data["taskTypeMeridian"].ToString() == "PM" ? 12 : 0));
                    time = time.AddMinutes(Convert.ToInt32(data["taskTypeMinute"].ToString()));

                    //Set the modified fields
                    td.taskName = data["taskName"].ToString();
                    td.taskDueDate = time;
                    td.taskTypeID = Convert.ToInt32(data["taskTypeId"]);
                    td.taskDetails = data["taskDetails"].ToString();
                }
                else //We are deleting the task
                {
                    //TASK must be deleted before TASKDETAIL. Both of these must be deleted or else a TASK is left behind
                    e.TASKs.DeleteObject(td); //Mark td's associated task for deletion

                }

                //Commit the changes
                int change = e.SaveChanges(); //Change will be > 0 on success

                redirectURL = data["redirectURL"].ToString();
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return Redirect(redirectURL);
        }

        [HttpGet]

        public ActionResult DeleteTaskHome(int taskID, string redirectURL)
        {
            ViewBag.Header = "Dashboard";

            try
            {
                //Try to redirect to the EditTask's delete functionality. It will take it from there.
                //Spoof a form collection with the task's ID
                FormCollection spoof = new FormCollection();
                spoof.Add("taskId", taskID + "");
                spoof.Add("redirectURL", redirectURL);

                return EditTask("Delete", spoof);
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }
        }

        public ActionResult AddTask()
        {
            try
            {
                ViewBag.Header = "Add a Task";

                // do not need anything
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View();
        }

        [HttpPost]
        public ActionResult AddTask(string dummydata/*Task object*/)
        {
            try
            {
                ViewBag.Header = "Add a Task";

                // do not need anything
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View(/*Task object*/);
        }

        public ActionResult About()
        {
            try
            {
                ViewBag.Header = "About";

                // do not need anything
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View();
        }

        public ActionResult ToggleTaskComplete(int id, int i)
        {
            ContentResult result = new ContentResult();
            try
            {
                bool b;
                string s;
                if (i == 0)
                {
                    b = false;
                    s = "Task incomplete";
                }
                else
                {
                    b = true;
                    s = "Task complete";
                }
                ThailandEntities thai = new ThailandEntities();
                TASK ChangeTask = thai.TASKs.Single(c => c.taskID == id);
                ChangeTask.taskComplete = b;
                thai.SaveChanges();

                result = Content(s);
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return result;
        }

        public ActionResult Error(string errorID)
        {
            try
            {
                // I tried setting the ViewBag from the AdminController, Nothing here...
                ViewBag.Header = "An Error Occcurred";
                if (errorID != null)
                {
                    ViewBag.errorCode = errorID;
                }
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View();
        }
    }
}
